<%@ page import="battleship.Game" %>
<%@ page import="battleship.PlayerShip" %>
<%@ page import="battleship.Ship" %>
<jsp:useBean id="Constants" class="battleship.Constants" scope="page" />
<jsp:useBean id="LoginInfo" class="battleship.LoginInfo" scope="page" />
<jsp:useBean id="GameBean" class="battleship.GameBean" scope="page" />
<jsp:setProperty name="GameBean" property="*" />
<% if (!LoginInfo.loggedIn(session)) { %>
    <jsp:forward page="index.jsp" />
<% }
final String pid = session.getAttribute("uid").toString();
final Game g = GameBean.getGameObj();
if (g == null || g.getMessage(pid) == null) { %>
    <jsp:forward page="index.jsp" />
<% } %>
<%= Constants.DOCTYPE %>
<html>
<head>
<%= Constants.META_CONTENT %>
<title><%= Constants.TITLE %> - Battle Station</title>
<%= Constants.LINK_CSS %>
<script type="text/javascript">
var boardLength = <%= Game.BOARD_LENGTH %>;
var selectedShip;
var selectedCell;
var ships = [];
var timestamp;

/**
 * Refresh the page (without posting) if the Game object was updated since the
 * page loaded.
 */
function ajaxUpdate() {
    var xmlhttp;
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            var s = xmlhttp.responseText;
            var iLeft = s.indexOf('\u003c!--') + 4;
            var iRight = s.indexOf('--\u003e', iLeft);
            var currentStamp = parseInt(s.substring(iLeft, iRight), 10);
            if (timestamp < currentStamp) {
                window.location.href = 'game.jsp?gid=' + <%= request.getParameter("gid") %>;
            }
        }
    }
    var url = 'gametimestamp.jsp?gid=' + <%= request.getParameter("gid") %>;
    xmlhttp.open('GET', url, true);
    xmlhttp.send();
}

function nudgeShip(evt) {
    if (!!selectedShip && selectedShip.parentNode === document.body) {
    }
}

/**
 * Deploys the selected ship object at the given cell.
 */
function deployShip(td) {
    if (!!selectedShip) {
        selectedShip.style.borderStyle = 'none';
        var img = selectedShip;
        if (img.parentNode.tagName !== 'DIV') {
            img.parentNode.appendChild(document.createTextNode(img.title));
            img.parentNode.removeChild(img);
            // CSS position doesn't work for img on Blackberry
            var div = document.createElement('div');
            div.style.position = 'absolute';
            div.appendChild(img);
            document.body.appendChild(div);
        }
        img.parentNode.style.position = 'absolute';
        img.parentNode.style.left = td.style.left;
        img.parentNode.style.top = td.style.top;
        
        var inputCoord = document.getElementById(selectedShip.title
                .replace(/ /g, '_') + '<%= GameBean.COORDINATE_SUFFIX %>');
        inputCoord.value = td.title;
        
        selectedShip = null;
    }
}

/**
 * Return the (x, y) coordinates represented by a string of the form /^[A-Z]\d$/
 */
function parseCoordinates(xy) {
    return [xy.charCodeAt(0) - 65, parseInt(xy.substring(1), 10)];
}

/**
 * Select a ship for deployment.
 */
function selectShip(e) {
    if (selectedShip === e) {
        e.style.borderStyle = 'none';
        selectedShip = null;
    } else {
        if (!!selectedShip) {
            selectedShip.style.borderStyle = 'none';
        }
        selectedShip = e;
        e.style.borderColor = '<%= GameBean.HIGHLIGHT_COLOUR %>';
        e.style.borderStyle = 'solid';
    }
}

/**
 * Write the title of the current element to the contents of the attack input.
 */
function setCoords(td) {
    var inputAttack = document.getElementById('<%= GameBean.INPUT_ATTACK_NAME %>');
    if (!!inputAttack) {
        inputAttack.value = td.title;
        if (!!selectedCell) {
            selectedCell.className = '';
        }
        selectedCell = td;
        selectedCell.className = 'selected';
    }
}

/**
 * Return true iff the forms appear to be correct.
 */
function validateForm() {
    if (!document.getElementById('<%= GameBean.INPUT_ATTACK_NAME %>')) {
        // Setup phase
        var occupied = []; // 2D boolean array of occupied coordinates
        for (var i = 0; i < boardLength; i++) {
            var row = [];
            for (var j = 0; j < boardLength; j++) {
                row.push(false);
            }
            occupied.push(row);
        }
        
        // De-select images
        selectedShip = null;
        for (var i in ships) {
            document.getElementById(ships[i].name.replace(' ', '_')
                    + '<%= GameBean.IMAGE_SUFFIX %>').style.borderStyle = 'none';
        }
        
        for (var i in ships) {
            var inputCoord = document.getElementById(ships[i].name
                    .replace(/ /g, '_') + '<%= GameBean.COORDINATE_SUFFIX %>');
            if (inputCoord.value.length == 0) {
                window.alert('You must deploy the ' + ships[i].name + '.');
                return false;
            }
            
            var topLeft = parseCoordinates(inputCoord.value);
            var x = topLeft[0], y = topLeft[1];
            var inputHV = document.getElementById(ships[i].name
                    .replace(/ /g, '_') + '<%= GameBean.ORIENTATION_SUFFIX %>');
            if (inputHV.value === '<%= GameBean.ORIENTATION_HORIZONTAL %>') {
                for (var j = 0; j < ships[i].length; j++) {
                    if (x + j >= boardLength || occupied[x + j][y]) {
                        var img = document.getElementById(ships[i].name
                                .replace(' ', '_') + '<%= GameBean.IMAGE_SUFFIX %>');
                        img.style.borderColor = 'red';
                        img.style.borderStyle = 'solid';
                        
                        if (x + j >= boardLength) {
                            window.alert('Your ' + ships[i].name + ' is out of bounds.');
                        } else {
                            window.alert('Your ships cannot overlap each other.');
                        }
                        return false;
                    }
                    occupied[x + j][y] = true;
                }
            } else {
                for (var j = 0; j < ships[i].length; j++) {
                    if (y + j >= boardLength || occupied[x][y + j]) {
                        var img = document.getElementById(ships[i].name
                                .replace(' ', '_') + '<%= GameBean.IMAGE_SUFFIX %>');
                        img.style.borderColor = 'red';
                        img.style.borderStyle = 'solid';
                        
                        if (y + j >= boardLength) {
                            window.alert('Your ' + ships[i].name + ' is out of bounds.');
                        } else {
                            window.alert('Your ships cannot overlap each other.');
                        }
                        return false;
                    }
                    occupied[x][y + j] = true;
                }
            }
        }
    }
    return true;
}

/**
 * Toggle between enemy/friendly grid view.
 */
function toggleGrid() {
    var grids = [document.getElementById('enemygrid'),
            document.getElementById('mygrid')];
    var statuses = [document.getElementById('enemystatus'),
            document.getElementById('mystatus')];
    for (var i in grids) {
        if (grids[i].style.display === 'none') {
            grids[i].style.display = 'inline';
            statuses[i].style.display = 'inline';
            var e = document.getElementById('gridshown');
            if (!!e) {
                while (e.hasChildNodes()) {
                    e.removeChild(e.firstChild);
                }
                e.appendChild(document.createTextNode(grids[i].title));
            }
        } else {
            grids[i].style.display = 'none';
            statuses[i].style.display = 'none';
        }
    }
}

function toggleOrientation(e) {
    var input = e.nextSibling;
    var current = input.value;
    if (current === '<%= GameBean.ORIENTATION_HORIZONTAL %>') {
        input.value = '<%= GameBean.ORIENTATION_VERTICAL %>';
    } else {
        input.value = '<%= GameBean.ORIENTATION_HORIZONTAL %>';
    }
    
    var shipName = input.name.substring(0, input.name.length
            - <%= GameBean.ORIENTATION_SUFFIX.length() %>);
    var img = document.getElementById(shipName.replace(/ /g, '_')
            + '<%= GameBean.IMAGE_SUFFIX %>');
    img.src = '<%= GameBean.IMAGE_PATH %>' + shipName + input.value + '.png';
}

/**
 * Expand or collapse the next sibling of the parent of the given <a> node.
 */
function toggleShow(a) {
    while (a.hasChildNodes()) {
        a.removeChild(a.firstChild);
    }

    var div = a.parentNode.nextSibling;
    if (div.style.display == 'none') {
        div.style.display = 'inline';
        a.appendChild(document.createTextNode('\u2212'));
    } else {
        div.style.display = 'none';
        a.appendChild(document.createTextNode('+'));
    }
}
</script>
</head>
<body>
<%= LoginInfo.getLinks(request) %>
<% GameBean.process(request); %>

<div id="enemygrid" title="Enemy"><%= GameBean.getGameObj().getEnemyGrid(pid) %></div>
<div id="mygrid" title="Friendly"><%= GameBean.getGameObj().getMyGrid(pid) %></div>
<script type="text/javascript">
document.getElementById('<%= g.validateSetup(pid) ? "mygrid" : "enemygrid" %>').style.display = 'none';
</script>

<form action="game.jsp?gid=<%= request.getParameter("gid") %>" method="post" onSubmit="return validateForm()">
<div id="notthegrid" style="position: absolute; left: <%= (Game.BOARD_LENGTH + 1) * GameBean.CELL_SIZE + GameBean.OFFSET_X + GameBean.PADDING_RIGHT %>px;">
    <div class="battlemessage"><%= g.getMessage(pid) %></div>
<% if (g.validateSetup(pid)) {
    if (g.opponentSetup(pid)) { %>
        <div style="position: fixed; bottom: 0; left: 0; border: solid 1px black; background-color: white;">
            <div style="float: right">[<a href="javascript:if(false){}" onClick="toggleShow(this)">?</a>]</div><div style="display: none;">
                <table style="white-space: nowrap;">
                    <caption>Legend</caption>
                    <tr>
                        <td class="legend hit"></td>
                        <td>Hit</td>
                    </tr>
                    <tr>
                        <td class="legend miss"></td>
                        <td>Miss</td>
                    </tr>
                    <tr>
                        <td class="legend lastmovehit"></td>
                        <td>Last move, hit</td>
                    </tr>
                    <tr>
                        <td class="legend lastmovemiss"></td>
                        <td>Last move, miss</td>
                    </tr>
                </table>
            </div>
        </div>
        <% if (g.getWinner() == null) { %>
            <div style="padding-bottom: 1em;">
            <% if (pid.equals(g.getTurn())) { %>
                Click a target and click "Fire!"<br>
                <input type="text" class="coords" maxlength="2" name="<%= GameBean.INPUT_ATTACK_NAME %>" id="<%= GameBean.INPUT_ATTACK_NAME %>">
                <input type="submit" value="Fire!">
            <% } else { %>
                Waiting for other player to move...
            <% } %>
            </div>
        <% } else { %>
            <!--Display enemy ships-->
            <script type="text/javascript">
            var parent = document.getElementById('enemygrid');
            if (!!parent) {
            var img;
            <% for (final PlayerShip ps : g.getEnemyShips(pid)) {
                final int[][] occupied = ps.getOccupiedCoords();
                final String orientation = occupied[0][0] == occupied[1][0] ? GameBean.ORIENTATION_VERTICAL : GameBean.ORIENTATION_HORIZONTAL; %>
                img = document.createElement('img');
                img.src = '<%= GameBean.IMAGE_PATH + ps.s.name + orientation %>.png';
                img.alt = '';
                img.style.position = 'absolute';
                img.style.left = '<%= GameBean.getCoordY(occupied[0][0]) %>px';
                img.style.top = '<%= GameBean.getCoordY(occupied[0][1]) %>px';
                parent.appendChild(img);
            <% } %>
            }
            </script>
        <% } %>
        <div>Grid shown: <span id="gridshown" style="font-weight: bold;">Enemy</span> (<a href="javascript:toggleGrid();">toggle</a>)</div>
        <script type="text/javascript">
        var parent = document.getElementById('mygrid');
        if (!!parent) {
        var img;
        <% for (final PlayerShip ps : g.getMyShips(pid)) {
            final int[][] occupied = ps.getOccupiedCoords();
            final String orientation = occupied[0][0] == occupied[1][0] ? GameBean.ORIENTATION_VERTICAL : GameBean.ORIENTATION_HORIZONTAL; %>
            img = document.createElement('img');
            img.src = '<%= GameBean.IMAGE_PATH + ps.s.name + orientation %>.png';
            img.alt = '';
            img.style.position = 'absolute';
            img.style.left = '<%= GameBean.getCoordY(occupied[0][0]) %>px';
            img.style.top = '<%= GameBean.getCoordY(occupied[0][1]) %>px';
            parent.appendChild(img);
        <% } %>
        }
        </script>
        
        <table id="enemystatus" class="shipstatus">
            <caption>Ship status</caption>
        <% for (final PlayerShip ps : g.getEnemyShips(pid)) { %>
            <tr>
                <td><img src="<%= GameBean.IMAGE_PATH + ps.s.name %>H.png" alt="" title="<%= GameBean.capitalizeFirst(ps.s.name) %>"></td>
                <td>
                    <% if (ps.getHealth() == 0) { %>
                        <img src="<%= GameBean.IMAGE_PATH %>destroyed.png" alt="Destroyed">
                    <% } %>
                </td>
            </tr>
        <% } %>
        </table>
        
        <table id="mystatus" class="shipstatus" style="display: none;">
            <caption>Ship status</caption>
        <% for (final PlayerShip ps : g.getMyShips(pid)) { %>
            <tr>
                <td><img src="ships/<%= ps.s.name %>H.png" alt="" title="<%= GameBean.capitalizeFirst(ps.s.name) %>"></td>
                <td class="shiphealth">
                    <% final int health = ps.getHealth();
                    final int healthLost = ps.s.length - health;
                    for (int i = 0; i < health; i++) {
                        %><img src="ships/health.png" alt="&#9829;"><%
                    }
                    for (int i = 0; i < healthLost; i++) {
                        %><img src="ships/health_lost.png" alt="&#9825;"><%
                    } %>
                </td>
            </tr>
        <% } %>
        </table>
    <% } else { %>
        Waiting for opponent to place their ships...
    <% } %>
    <script type="text/javascript">
    timestamp = <%= g.getTimestamp() %>;
    window.setInterval('ajaxUpdate()', 5000);
    <% if (g.getTurn().equals(Constants.COMPUTER_UID) && g.getWinner() == null) { %>
	window.setInterval('window.location.href = \'game.jsp?gid=\' + <%= request.getParameter("gid") %>;', 2000);
	<% } %>
    </script>
<% } else { %>
    <table class="bordered" style="white-space: nowrap;">
        <tr>
            <th>Ship</th>
            <th>Orientation</th>
        </tr>
    <% for (Ship s : g.ships) { %>
        <tr>
            <td><img src="ships/<%= s.name + GameBean.ORIENTATION_HORIZONTAL %>.png" id="<%= s.name.replace(' ', '_') + GameBean.IMAGE_SUFFIX %>" onClick="selectShip(this)" style="border-color: <%= GameBean.HIGHLIGHT_COLOUR %>; border-style: none; border-width: 2px;" title="<%= s.name %>"></td>
            <td>
                <!--Preload image--><img style="display: none;" src="ships/<%= s.name + GameBean.ORIENTATION_VERTICAL %>.png">
                <input type="hidden" id="<%= s.name.replace(' ', '_') + GameBean.COORDINATE_SUFFIX %>" name="<%= s.name %>"><input type="button" value="Toggle" onClick="toggleOrientation(this)"><input type="hidden" name="<%= s.name + GameBean.ORIENTATION_SUFFIX %>" id="<%= s.name.replace(' ', '_') + GameBean.ORIENTATION_SUFFIX %>" value="<%= GameBean.ORIENTATION_HORIZONTAL %>">
            </td>
        </tr>
    <% } %>
        <tr>
            <td colspan="4"><input type="submit" value="Deploy ships" style="width: 100%;"></td>
        </tr>
    </table>
    <script type="text/javascript">
    document.onkeypress = nudgeShip;
    <% for (Ship s : g.ships) { %>
        ships.push({name: '<%= s.name %>', length: <%= s.length %>});
    <% } %>
    </script>
    <div>Select a ship by clicking its image, and then click on the grid to deploy it.  The ship's top-left corner will move to the selected coordinate.</div>
<% } %>
</div>
</form>
</body>
</html>